A computer program typically includes at least some conditional instructions. A conditional instruction is an instruction that is executed only if a certain condition is satisfied. A branch is a sequence of instructions that is executed if a condition associated with the branch is satisfied. A predicate is a variable associated with one or more instructions of the program and indicating whether these instructions are to be executed or not. A branch may thus be implemented by assigning the same predicate to each instruction of the branch. A predicate may notably be a boolean variable. When the predicate is true, the branch will be executed. When the predicate is false, the branch will not be executed. The use of predicates in programming is also referred to as predicating or as branch-predicating. Predicates are used, for example, to predicate a branch instruction, thus implementing a conditional branch. Predicating can be seen as an alternative to using branch instructions, and they can be very useful for executing the program using multiple pipelines. Predicates can be implemented in hardware (HW), software (SW), or in a combination of both HW and SW.
On some data processing machines, a program may be stored in the form of a sequence of instruction groups. An instruction group is a set of one or more instructions. Each instruction group may thus comprise one or more instructions. One instruction group may be executed per execution cycle. Instruction groups comprising two or more instructions may also be referred to as Very Long Instruction Words (VLIW) or Variable Length Execution Sets (VLESs), depending on the architecture or the manufacturer. Each instruction in the instruction group may be assigned a predicate to indicate whether the instruction is to be executed. Predicates thus allow to activate and deactivate any instruction in a given instruction group. The innovation described herein is neither limited to multi-issue processors, nor to Very Long Instruction Word (VLIW) processors. The invention is in fact applicable to any processor that has one or more predicates, including, but not limited to, multi-issue processors.
The value of a predicate may be changed (updated) in the course of executing the program. The predicate may, for example, change from true to false or vice versa. In fact, the instructions of a program may include instructions for changing the value of a predicate. The predicate values may be reported for each or for selected execution cycles in a trace (predicate trace) for the purpose of, e.g., debugging or code coverage analysis. The predicate trace may enable a programmer or an analysis program to reconstruct the predicate values which were assumed during a run of the program. The predicate values may, for example, enable an external tool to determine, for each conditionally executed instruction, whether the instruction was executed or not. This information may notably be used for code coverage analysis, an important verification technique used by software (SW) developers. Indeed, it may be insufficient to know the exact execution flow because any instruction in the flow may or may not have been executed, depending on the value of the predicate assigned to that instruction.
In any processor, real-time trace bandwidth is limited, regardless of whether the trace is written to memory or reported on, e.g., an input-output port, to trace collecting hardware (HW). For example, the StarCore SC3900 processor developed by Freescale has six predicates. Each of these predicates may be changed during each execution cycle. That is, none, one, two, three, four, five, or six of the six predicates may be changed during a given execution cycle. The SC3900 supports programs with instruction groups, which can execute up to eight different instructions per cycle. The SC3900 allows to predicate any instruction in the instruction group by any one of the six predicates. Reporting the value of each predicate in each instruction group may consume too much of the available bandwidth. It is pointed out that predicate tracing comes on top of flow tracing. Flow tracing enables a developer to know which instruction groups in the program were executed, but not which instructions inside an instruction group were executed.